﻿using System.Threading;
using DBServer.Selenium.Extenium.Exception;
using DBServer.Selenium.Extenium.Path;
using Selenium;

namespace DBServer.Selenium.Extenium.Fixtures
{
    public class DialogFixture<T> : ExtComponentFixture 
        where T : DialogFixture<T>
    {    
        private const string Name = "window.Ext";

        public DialogFixture(ISelenium driver) : base(driver, new PlainPath(Name))
        {
        }

        public void Close()
        {
            SafeExecDialog("window.Ext.MessageBox.getDialog().close()");
        }

        public T RequireVisible()
        {
            var contains = bool.Parse(SafeExecDialog("window.Ext.MessageBox.getDialog().isVisible()"));

            if (!contains)
            {
                throw new ExteniumException("Dialog is not visible");
            }
            return (T)this;
        }

        public T RequireInvisible()
        {
            Wait(() => bool.Parse(SafeExecDialog("window.Ext.MessageBox.getDialog().isVisible()")) == false);

            var visible = bool.Parse(SafeExecDialog("window.Ext.MessageBox.getDialog().isVisible()"));

            if (visible)
            {
                throw new ExteniumException("Dialog is visible");
            }
            return (T)this;
        }

        public T RequireMessage(string message)
        {
            RequireVisible();
            
            Wait(() => ContainsMessage(message) == true );           
           
            if ( !ContainsMessage(message) )
            {
                throw new ExteniumException("Dialog does not contain the message required");
            }
            return (T)this;
        }

        /// <summary>
        /// Private method only to return whether the message is present or not
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        private bool ContainsMessage(string message)
        {
            return SafeExecDialog("window.Ext.MessageBox.getDialog().getEl().dom.innerHTML").Contains(message);
        }


        protected string SafeExecDialog(string command)
        {
            const int maxRetry = 10;
            const int sleepInterval = 500;

            for (var i = 0; i < maxRetry; i++)
            {
                try
                {
                    return Driver.GetEval(command);
                }
                catch (SeleniumException)
                {
                    if (i < maxRetry)
                    {
                        Thread.Sleep(sleepInterval);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            return null;
        }
    }





    public class DialogFixture : DialogFixture<DialogFixture>
    {
        public DialogFixture(ISelenium driver) 
            :base(driver)
        {}
    }
}